const { getParam, nilValue, emptyValue, emptyString } = require("../base");
const { DataFormatter } = require("./dataHandle");
const { BaseErr, ParamErr, SignErr } = require("./error");
const crypto = require("crypto");
const SignSecret = "yiwayimadai";
class Uitls {
    constructor() {
        this.getParam = getParam;
        this.nilValue = nilValue;
        this.emptyValue = emptyValue;
        this.emptyString = emptyString;
    }
    padStr(o, length = 2, fill = "0") {
        return String(o).padStart(length, fill);
    }
    delay(t) {
        if (typeof t !== "number" || t <= 0) {
            return Promise.resolve();
        }
        return new Promise((resolve) => {
            setTimeout(() => {
                resolve();
            }, t);
        });
    }

    // 加个包装 promise
    async awaitWrap(p) {
        let pro_ = p;
        if (Object.prototype.toString.call(pro_) !== "[object Promise]") {
            pro_ = Promise.resolve(p);
        }
        try {
            return [null, await pro_];
        } catch (err) {
            return [err, null];
        }
    }
    convertBodyObj(body, headers) {
        // 判断 header
        if (this.nilValue(headers)) {
            return this.defaultTransformBody(body);
        }
        // 判断 content-type
        let contentType = headers["content-type"] || headers["Content-Type"] || "";
        if (contentType.indexOf("/json") >= 0) {
            // json
            return DataFormatter.json(body);
        } else if (contentType.indexOf("/x-www-form-urlencoded") >= 0) {
            // url
            return DataFormatter.urlencoded(body);
        } else if (contentType.indexOf("/xml") >= 0) {
            return DataFormatter.xml(body);
        }
        return {};
    }

    // 默认的转换逻辑
    defaultTransformBody(body) {
        if (typeof body === "string") {
            let tmp = null;
            // 是不是key value形式的
            try {
                tmp = JSON.parse(body);
            } catch (e) {}
            // urlencode
            if (!tmp) {
                let partArr = body.split("&");
                let resultBody = {};
                for (let i = 0; i < partArr.length; i++) {
                    let part = partArr[i];
                    let single = part.split("=");
                    if (single.length === 2) {
                        resultBody[single[0]] = decodeURIComponent(single[1]);
                    }
                }
                tmp = resultBody;
            }
            return tmp || {};
        } else if (typeof body === "object") {
            return body;
        }
        return {};
    }

    // dcloud 要求的格式
    resPack(data, err) {
        if (typeof err !== "undefined" && err !== null) {
            let targetErr = err;
            if (!(err instanceof BaseErr)) {
                targetErr = new BaseErr();
            }
            return targetErr.resMaker();
        }
        // 虽然返回了数据, 但是 code 不对
        if (data && !this.nilValue(data.errCode) && data.errCode !== 0) {
            let inside_err = new InsideErr(data);
            return inside_err.resMaker();
        }
        return {
            errCode: 0,
            errMsg: "ok拉",
            data: data || {},
        };
    }

    resErr(err) {
        return this.resPack(null, err);
    }
    resData(data) {
        return this.resPack(data, null);
    }
    // 签名校验
    checkSign(event) {
        let { sign, timestamp, dxd } = event.headers || {};
        if (this.nilValue(sign) || this.nilValue(timestamp) || this.nilValue(dxd)) {
            return this.resErr(new ParamErr("sign"));
        }
        // 是不是数字
        let timestampNumber = this.getNumberValue(timestamp);
        if (nilValue(timestampNumber)) {
            return this.resErr(new ParamErr("timestamp"));
        }
        let dxdNumber = this.getNumberValue(dxd);
        if (nilValue(dxdNumber)) {
            return this.resErr(new ParamErr("dxd"));
        }

        // 判断时间戳
        let currentDate = Date.now();
        if (Math.abs(currentDate - timestampNumber) > 1000 * 10) {
            return this.resErr(new BaseErr(-5001, "请求已经过期"));
        }

        // 解析body
        let body = {};
        if (typeof event.body === "object") {
            body = event.body;
        } else if (typeof event.body === "string") {
            try {
                body = JSON.parse(event.body);
            } catch (e) {}
        }
        // key 正序
        let sortKeys = Object.keys(body).sort();
        // 拼接
        let sortArr = sortKeys.map((key) => {
            return `${key}:${body[key]}`;
        });
        let signStr = sortArr.join("");
        signStr = `${signStr}${timestampNumber}${dxdNumber}`;
        let hash = crypto.createHmac("sha256", SignSecret).update(signStr, "utf8").digest("hex");
        let correctSign = Buffer.from(hash).toString("base64");
        console.log(sign, correctSign);
        return sign === correctSign ? null : this.resErr(new SignErr());

        // crypto-js
        // const hmacSHA256 = require('crypto-js/hmac-sha256');
        // const Base64 = require('crypto-js/enc-base64');
        // const Utf8 = require('crypto-js/enc-utf8');

        // const SignSecret = "yiwayimadai";

        // let hash = hmacSHA256("aa:dxd&djcc:dxdgg:djww:allzz:661654061813040", SignSecret);
        // var result = Base64.stringify(Utf8.parse(hash));
        // console.log(result);
    }

    /**
     * 转换 的日期
     * @param {Object} date 转成 utc8 时间
     * @param {Number} offset 偏移量 getTimezoneOffset
     */
    UTCConverDateOffset(date, offset) {
        let currentTimezone = date.getTimezoneOffset();
        let utcDate = date.getTime() + (currentTimezone - offset) * 60 * 1000;
        let result = new Date(utcDate);
        return result;
    }

    /**
     * 转换 的日期
     * @param {Object} date 转成 utc8 时间
     * @param {Number} timezone 时区
     */
    UTCConverDate(date, timezone) {
        let targetDate = null;
        if (typeof date === "number") {
            targetDate = new Date(date);
        } else {
            targetDate = date;
        }
        if (targetDate.toString() === "Invalid Date") {
            return null;
        }
        let targetTimezone = timezone * 60 * -1;
        return this.UTCConverDateOffset(targetDate, targetTimezone);
    }

    UTC8ConverDate(date) {
        return this.UTCConverDate(date, 8);
    }

    /**
     * 格式显示 日期
     * @param {Object} date 日期
     */
    formatterDate(date) {
        let targetDate = this.UTC8ConverDate(date);
        if (!targetDate) {
            return "";
        }

        let { year, month, day, hour, minute, second } = this.parseDate(targetDate);
        let des = this.getDateDes(year, month, day, hour, minute, second);

        // 判断星期几
        let today = this.UTC8ConverDate(new Date());
        let todayPart = this.parseDate(today);

        // 其他描述, 星期几
        let weekDayDes = ["天", "一", "二", "三", "四", "五", "六"];
        let partDes = "星期" + weekDayDes[targetDate.getDay()];
        if (todayPart.year === year && todayPart.month === month) {
            if (todayPart.day + 2 === day) {
                partDes = "是后天喔";
            } else if (todayPart.day + 1 === day) {
                partDes = "是明天喔";
            } else if (todayPart.day === day) {
                partDes = "就是今天啦";
            }
        }
        return `${des} ${partDes}`;
    }

    // 日期描述
    getDateDes(year, month, day, hour, minute, second, millisecond) {
        let pad = (o) => {
            return String(o).padStart(2, "0");
        };
        let part1 = [year, month, day].map((e) => pad(e)).join("/");
        let part2 = [hour, minute, second].map((e) => pad(e)).join(":");
        return [part1, part2, pad(millisecond)].join(" ");
    }
    // 时间描述
    baseDateDes(date) {
        let utc8 = this.UTC8ConverDate(date);
        let { year, month, day, hour, minute, second, millisecond } = this.parseDate(utc8);
        return this.getDateDes(year, month, day, hour, minute, second, millisecond);
    }
    // 解析 日期
    parseDate(date) {
        let year = date.getFullYear();
        let month = date.getMonth() + 1;
        let day = date.getDate();
        let hour = date.getHours();
        let minute = date.getMinutes();
        let second = date.getSeconds();
        let millisecond = date.getMilliseconds();
        return {
            year,
            month,
            day,
            hour,
            minute,
            second,
            millisecond,
        };
    }
    // 获取数字结果
    getNumberValue(n) {
        if (nilValue(n)) {
            return null;
        }
        if (typeof n === "number") {
            return n;
        }
        if (typeof n === "string") {
            let tmp = n.trim();
            if (tmp.length === 0) {
                return null;
            }
            let num = Number(tmp);
            if (Number.isNaN(num)) {
                return null;
            }
            return num;
        }
        // 最终就是 null
        return null;
    }
}

module.exports = {
    Uitls,
};
